Close the P1 Install-Model Gaps: G1 G2 G3 G6 G8 - #690
Conversation
The validate-task.yml step the G8 handoff asks for landed in #676, before the register merged, so the row's Checked claim was stale on arrival. The row records the resolution and its provenance instead of being deleted, per the register's maintenance rule.
A bare run reads only the declaration at its own working directory, so a run started in a subdirectory of a repo carrying a host-tools.json overlay skipped that overlay without a word. The run names the skipped directory and the --repo re-run that counts it. Closes register row G2.
A failed floor named the tool, the defect, and the source prose, and left the operator to rediscover which installer provides the tool. Each floored catalog entry carries a per-platform remedy command, printed as a REMEDY line with host-setup/ paths resolved against the checkout, so the failure carries its own fix. test_bootstrap.py keeps the mapping total and pointing at tools the installers manage. Closes register row G3.
A host bootstrapped end to end had every tool and no fleet skills. The bootstrap host mode ends with an install-skills step on both platforms, a --skills action runs it alone, and the report reads the stamp beside the other status lines. The loaders hand their resolved commit to the installer, since a tarball tree has no .git, so the stamp stays checkable. docs/host-setup.md gains the Fleet Skills Install section, and the README names four deployed things. The claude CLI stays out of the tool catalog, the installer degrades without it and says so. Closes register row G1, cross-linking #671 and #673 which touch the same scripts.
A machine with stale skills behaves like one that never installed them, and the symptom is a rule that keeps needing restating. The cadence, re-run the installer when --report exits non-zero and after any hub merge touching .agents/skills/, is stated in docs/host-setup.md and in the fleet-conformance-check skill, which routes the symptom to the report it already runs. No new tooling, by design. Closes register row G6, which completes the P1 install-model roadmap phase.
There was a problem hiding this comment.
Pull request overview
This PR closes the fleet map’s P1 “skills install model” gaps by wiring fleet skills installation into cold-start bootstraps, making host tool floor failures self-remediating, warning on silently skipped repo overlays, and documenting/recording staleness cadence and already-closed CI coverage.
Changes:
- Add per-platform
remedycommands to the host tools spec/schema and print them inhost_gate.pybelow-floor findings (with checkout-relative resolution). - Wire fleet skills installation into Linux/Windows bootstrap flows (new
install-skills.*drivers, bootstrap--skillsaction, docs + README updates) and support tarball installs viaSKILLS_SOURCE_COMMIT. - Close/register G2/G6/G8 in
docs/fleet-map.mdand update thefleet-conformance-checkskill with the refresh cadence.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| STANDUP.md | Updates section 0 guidance around bare host_gate.py runs and overlay behavior. |
| spec/validate.py | Enforces remedy presence/shape when a floor is declared. |
| spec/host-tools.schema.json | Requires remedy alongside source when minimum declares a floor. |
| spec/host-tools.json | Adds remedy commands and documents remedy semantics in the spec note. |
| spec/host-tools-local.schema.json | Extends local overlay schema to allow a remedy object. |
| scripts/test_skills_install.py | Adds tests for SKILLS_SOURCE_COMMIT fallback and precedence vs git. |
| scripts/test_host_gate.py | Adds tests for remedy output, repo-relative remedy resolution, and overlay warnings. |
| scripts/test_bootstrap.py | Adds remedy-mapping coverage assertions; includes new install-skills scripts in presence/executable checks. |
| scripts/skills_install.py | Supports archive/tarball installs via SKILLS_SOURCE_COMMIT in source_ref(). |
| scripts/host_gate.py | Prints REMEDY: under below-floor failures and warns on skipped overlays in bare runs. |
| README.md | Adds “Install the Fleet Skills” and updates “Using This Repo” to four deployed items. |
| host-setup/windows/install-skills.ps1 | New Windows driver to run scripts/skills_install.py with Python discovery. |
| host-setup/README.md | Documents install-skills as a deliberate exception (Python + not independently fetchable). |
| host-setup/linux/install-skills.sh | New Linux driver to run scripts/skills_install.py with Python discovery. |
| host-setup/bootstrap.sh | Adds skills step to --host, adds --skills action, and reports skills status. |
| host-setup/bootstrap.ps1 | Adds -Skills action, runs skills in host mode, and hands SKILLS_SOURCE_COMMIT to the installer. |
| docs/host-setup.md | Adds “Fleet Skills Install” section, verify lines, and states refresh cadence. |
| docs/fleet-map.md | Updates diagrams/register rows to mark G1/G2/G3/G6/G8 as closed and records provenance. |
| .claude-plugin/fleet-skills/skills/fleet-conformance-check/SKILL.md | Adds “Refresh cadence” section in generated plugin form. |
| .claude-plugin/fleet-skills/.source-digest | Updates digest to reflect regenerated plugin content. |
| .agents/skills/fleet-conformance-check/SKILL.md | Adds “Refresh cadence” section in source skill form. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A malformed hub declaration crashed the below-floor path on a non-dict source or remedy, discarding the findings already collected, and a checkout path carrying a space printed a command that was not runnable as printed. platform_field() reads both fields crash-free, a non-dict remedy on a floored tool is a contract problem, and resolve_remedy() shell-quotes the resolved path, with the PowerShell call operator on Windows.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (2)
spec/host-tools.json:88
- On macOS, the
python3remedy isbrew install python, which will not upgrade an already-installed but below-floor Python. That means a below-floor host can re-run the printed command and still fail the floor. Make the remedy an upgrade-capable command (consistent with the other macOS remedies).
"macos": "brew install python",
docs/host-setup.md:247
- This sentence claims the host gate prints install source + a runnable install/upgrade command for missing required tools as well as below-floor tools, but
scripts/host_gate.pyonly emitsINSTALL FROM:/REMEDY:on the below-floor path. Please reword to match the actual output (or adjust the gate to print these lines for missing tools too).
The gate replaced a line that ran `--version` on each tool and read only whether it answered. That form reported a host carrying the broken `gh` as fully set up, which is the failure it exists to stop. It exits non-zero on a missing required tool or one below its floor, prints the defect behind the floor rather than the number alone, names where to install from, and prints the command that installs or upgrades the tool on the current platform, so the failure carries its own fix.
The verify prose read as though a missing required tool also prints INSTALL FROM and REMEDY lines, and only the below-floor path does. The sentence now says which failure carries which output.
|
Answering the 2 suppressed findings from the round-2 review on 7b298a5, which open no thread to resolve. The block reported "Suppressed comments (2)", and both are answered here. 1. Disproven. The Homebrew manpage for 2. Fixed in 62b7fb4. The sentence now scopes the |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (1)
spec/host-tools.json:90
- The macOS remedy for the Python floor uses
brew install python, which typically does not upgrade an already-installed (but outdated) formula. Since remedies are meant to fix a below-floor state, this should usebrew upgrade python(consistent with other Homebrew remedies in this file).
"remedy": {
"linux": "host-setup/linux/install-tools.sh --upgrade python",
"macos": "brew install python",
"windows": "host-setup/windows/install-tools.ps1 -Upgrade python"
}
The review keeps reading brew install as non-upgrading. The catalog note now carries the rationale: brew install upgrades an outdated formula per the Homebrew manpage, and brew upgrade refuses a tool Homebrew never installed, so install is the one form that fixes both below-floor states for an entry whose source is the platform.
|
Answering the 1 suppressed finding from the round-3 review on 62b7fb4, which opens no thread to resolve. The block reported "Suppressed comments (1)". 1. Disproven, same ground as the round-2 answer above: the Homebrew manpage's |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (2)
docs/fleet-map.md:213
- In the “Closing test” bullet, the link label
[scripts-readme]points to../scripts/README.md, so the visible textscripts/test_bootstrap.pylinks to the wrong document. Either link to the test file with its own reference, or render it as inline code to avoid a misleading link.
- **Closing test** - [`scripts/test_bootstrap.py`][scripts-readme] asserts the mapping stays total per platform, with the one recorded not-applicable exception, and that a remedy handing back into an installer names a tool that installer manages. [`spec/validate.py`][files] and the schema require a remedy on every hub floor. A repository overlay may still add a floor without one, in which case the failure degrades to the `INSTALL FROM:` source line.
scripts/host_gate.py:426
- The bare-run overlay warning prints a re-run command as
--repo {skipped}. If the repo path contains spaces, this example command won’t be copy/paste runnable in common shells. Consider quoting the path in the suggested--repoargument.
if skipped is not None:
# Outside --quiet, because a silently skipped overlay is the omission this line exists to name.
print(f' warning: {skipped} carries a host-tools.json overlay this bare run did not read - re-run with --repo {skipped} so its floors count')
The fleet map linked scripts/test_bootstrap.py and spec/validate.py text to the scripts README and files.json, and the same class of mismatch sat on two prose_lint.py mentions, so each file gets its own reference. The bare-run overlay warning quotes the --repo path it prints, so the re-run pastes back into a shell whole.
|
Answering the 2 suppressed findings from the round-4 review on 7f667d4, which open no thread to resolve. The block reported "Suppressed comments (2)", and both are answered here. 1. Fixed in 227e1bd. 2. Fixed in 227e1bd. The warning quotes the |
…Python CI Gates (#718) Thirty-one squashes, `56f4d7d..d54862a`. 115 files, +20436/-5298. **Merge with a merge commit, never a squash, and never with `--delete-branch`.** This pull request's head is `develop` itself. ## What lands **Fleet Skills.** The `.agents/skills/` source tree, the generated `.claude-plugin/` distribution, `scripts/build_dist.py` with its `--check` gate, and `scripts/skills_install.py` with its host stamp (#676). Packaged as skills on top of the scaffold: PR review conduct and Copilot instructions upkeep (#677), comment and doc style (#678), resync-a-repo and fleet-conformance-check (#679), the per-language codestyles (#680), git commit conventions and operational vs release workflow (#681), stand up a repo (#683), and repo-worktree (#717). Coverage gaps closed in three passes (#690, #691, #692) plus the P4 sentence-length opt-in (#697). **Host setup.** The Windows host-setup tooling and its PowerShell gate (#674), the Windows bootstrap loader (#682), Docker install and upgrade on Linux and Windows with a version floor (#701, #705), a `uv` floor in `spec/host-tools.json` (#698), self-healing of a shadowing `uv`, `jq`, or `git-restore-mtime` copy (#689), node's real winget package id (#696), and a README for the Linux host-setup nuances (#710). **Python and CI.** Python tooling in CI with the script tests moved to `scripts/tests` (#704), `ruff format` adopted and gated (#709), and the PSScriptAnalyzer claim conditioned on repos that carry `.ps1` files (#686). **Conduct rules.** Triage-order and scope guardrails in pr-review-conduct (#684), `pr_review.py wait` requesting a review rather than only polling for one (#685), a tech-agnostic signed-commit verification (#708), execution rather than analogy to verify platform-specific code (#715), and a unique worktree for every task (#717). **Docs.** The fleet map and gap register with peer messaging declared (#687), mermaid flow diagrams in the kept-authority docs (#702), and the map pointed at the shipped diagrams and current tooling (#703). ## Issues this promotion closes Each landed on `develop` on its own pull request. The keyword fires only on a merge into `main`, so it sits here rather than on the feature pull requests. Closes #700 Closes #707 Closes #711 Closes #712 Closes #714 Closes #688 #699 stays open on purpose: #717 shipped the layout convention and the skill, and the physical migration of existing checkouts is still tracked there. ## Review record Every squash closed its own Copilot loop on its own pull request before merging to `develop`. This promotion carries no new content of its own, so its review is the merged tree as a whole. ## Consequence worth stating The `GOVERNANCE.md` and `AGENTS.md` sections these squashes changed become the canonical the moment this reaches `main`, and every carrying repository reads as drifted from that point until it resyncs. That is the ordinary consequence of a canonical moving rather than a defect. The Skills installer added here is also how a machine picks the new skills up, so a session that keeps restating a rule already packaged as a skill is the signal to run it.
Why
The fleet map's P1 phase closes the skills install model. A bootstrapped host ended with every tool and no fleet skills, a failed tool floor named no runnable remedy, a bare
host_gate.pyrun silently skipped an enclosing repo's overlay, nothing stated the skills staleness cadence, and the register's G8 row described a CI gap that #676 had already closed before the register merged.What
One commit per register row, each editing its row in
docs/fleet-map.mdper the maintenance rule:validate-task.ymlhas runbuild_dist.py --checksince Scaffold fleet Skills: agents/skills source, dist build, installer #676, which predates the register's merge, so the row'sCheckedclaim was stale on arrival and the row now records the resolution and its provenance.host_gate.pywarns when a bare run's working directory sits inside a repo carrying ahost-tools.jsonoverlay it did not read, naming the--repore-run that counts it. An explicit--repoand--no-localstay silent. STANDUP section 0 states the residual case the warning cannot cover, a target that does not exist yet.spec/host-tools.jsonentry carries a per-platformremedycommand beside itssource, printed as aREMEDY:line under a below-floor failure, withhost-setup/paths resolved against the checkout so the command is runnable as printed. The schema andspec/validate.pyrequire it on every hub floor, andtest_bootstrap.pykeeps the mapping total per platform (git-restore-mtime/windows is the recorded not-applicable exception) and pointing at tools the installers actually manage.install-skillsstep on both platforms, a--skillsaction runs it alone, and the report mode reads the stamp beside the other status lines. The loaders hand their resolved commit to the installer viaSKILLS_SOURCE_COMMIT, since a tarball tree has no.git, so the stamp stays checkable and--reportcan exit zero on a fresh host.docs/host-setup.mdgains the "Fleet Skills Install" section and verify lines, andREADME.md"Using This Repo" names four deployed things. TheclaudeCLI stays out of the tool catalog: the installer degrades without it, lands the overlay half, and records the partial install. The new drivers keep the loader single-path and no-Python invariants intact, and the two recorded exceptions (Python last-in-line, independent fetchability) are stated inhost-setup/README.md. Cross-links Record why the host tooling carries no linter category, or decide that it should #671 and Align the linux host-setup scripts onto 'name one action' instead of 'the last one given wins' #673, which touch the same scripts and stay open on their own tracks.docs/host-setup.mdand thefleet-conformance-checkskill's new "Refresh cadence" section (plugin regenerated viabuild_dist.py), routing the restated-rule symptom toskills_install.py --report.Verification
Every
validate-task.ymlgate run locally and green: the ten script and spec self-tests, including new cases for the warning, the remedy mapping, and the handed-in commit, plusrepo_gate.py,prose_lint.pywith CI's check list,spec/validate.py,build_dist.py --check, markdownlint, cspell on README and HISTORY, shellcheck and PSScriptAnalyzer via the same pinned containers CI uses, and all seven fleet-map mermaid blocks parse.